package lib

import (
	"blog/core/conf"
	"database/sql"
	"errors"
	"fmt"
	"time"

	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
)

var DBMapPool map[string]*sql.DB
var DBDefaultPool *sql.DB

var GORMMapPool map[string]*gorm.DB
var GORMDefaultPool *gorm.DB

/* =================================================================
	数据库系列 二次封装工具
 * =================================================================*/
func InitDbPool(path string) error {
	if err := conf.InitMySQLConf(path); err != nil {
		return err
	}

	//没有数据库配置文件 就 提示 信息
	if len(conf.IConfMySQLMap.List) == 0 {
		fmt.Printf("[INFO] %s%s\n", time.Now().Format(TimeFormat), " empty mysql config.")
	}

	DBMapPool = map[string]*sql.DB{}
	GORMMapPool = map[string]*gorm.DB{}

	for confName, dbConf := range conf.IConfMySQLMap.List {
		//fmt.Println( "数据库连接信息:",dbConf.DataSourceName)
		//================普通连接模式===============
		dbPool, err := sql.Open("mysql", dbConf.DataSourceName)
		if err != nil {
			return err
		}
		dbPool.SetMaxOpenConns(dbConf.MaxOpenConn)
		dbPool.SetMaxIdleConns(dbConf.MaxIdleConn)
		dbPool.SetConnMaxLifetime(time.Duration(dbConf.ConnMaxLifeTime) * time.Second)
		//测试链接
		err = dbPool.Ping()
		if err != nil {
			return err
		}

		//=================gorm连接方式===============
		dbGorm, err := gorm.Open("mysql", dbConf.DataSourceName)
		if err != nil {
			return err
		}
		dbGorm.SingularTable(true)
		err = dbGorm.DB().Ping()
		if err != nil {
			return err
		}

		dbGorm.LogMode(true)
		//接入日志 记录工具
		//dbGorm.SetLogger(&MysqlGormLogger{Trace: NewTrace()})

		//设置连接数据参数
		dbGorm.DB().SetMaxIdleConns(dbConf.MaxIdleConn)
		dbGorm.DB().SetMaxOpenConns(dbConf.MaxOpenConn)
		dbGorm.DB().SetConnMaxLifetime(time.Duration(dbConf.ConnMaxLifeTime) * time.Second)
		//存入DB 连接池
		DBMapPool[confName] = dbPool
		GORMMapPool[confName] = dbGorm

	}

	//赋值给 默认的连接池 方便直接调用 免得 用map形式 麻烦
	if dbPool, err := GetDBPool("default"); err == nil {
		DBDefaultPool = dbPool
	}
	if dbPool, err := GetGormPool("default"); err == nil {
		GORMDefaultPool = dbPool
	}
	return nil
}

func GetDBPool(name string) (*sql.DB, error) {
	if dbPool, ok := DBMapPool[name]; ok {
		return dbPool, nil
	}
	return nil, errors.New("get pool error")
}

func GetGormPool(name string) (*gorm.DB, error) {
	if dbPool, ok := GORMMapPool[name]; ok {
		return dbPool, nil
	}
	return nil, errors.New("get pool error")
}

func CloseDB() error {
	for _, dbPool := range DBMapPool {
		dbPool.Close()
	}
	for _, dbPool := range GORMMapPool {
		dbPool.Close()
	}

	return nil
}

//mysql日志打印类
type MysqlGormLogger struct {
	gorm.Logger
}
